﻿using System;
using System.Text;
using System.Collections.Generic;

namespace EpisodeWizard.Core
{

    /// <summary>
    /// Some websites do not give access to a single episode
    /// We have to parse the whole TV show page
    /// The pages contents is cached to avoir parsing them several times
    /// </summary>
    public abstract class QueryPluginCached : QueryPlugin
    {

		/// <summary>
        /// Holds info about a whole TV show and its episodes
        /// </summary>
        public class CachedShow
        {
			/// <summary>The ID used to identify the show in the database</summary>
			public string ID;

			/// <summary>The full name of the show</summary> 
			public string Name;

			/// <summary>True if the list of epsodes has already been retrieved</summary>
			public bool IsInCache;

			/// <summary>The list of episodes</summary>
            public Dictionary<string, EpisodeInfo> Episodes;
        }

        /// <summary>
        /// Dictionary of TV show already in the cache
        /// </summary>
        protected Dictionary<string, CachedShow> CachedShows;

		/// <summary>
		/// Constructor
		/// </summary>
		protected QueryPluginCached()
		{
			CachedShows = new Dictionary<string,CachedShow>();
		}


		protected abstract void AddShowToCache(CachedShow Show);


		/// <summary>
		/// Returns info on a particular episode
		/// </summary>
		public override EpisodeInfo GetEpisodeInfo(string ShowId, int Season, int Episode)
		{
			// If the show is not in the list
			// Then the website does not have it
			if (CachedShows.ContainsKey(ShowId) == false)
			{
				return null;
			}

			// If the show has not be loaded yet, retrieve the webpage
			CachedShow Show = CachedShows[ShowId];
			if (Show.IsInCache == false)
			{
				AddShowToCache(Show);
			}

			try
			{
				EpisodeInfo EpisodeQuery = Show.Episodes["s" + Season + "e" + Episode];
				return EpisodeQuery;
			}
			catch (System.Collections.Generic.KeyNotFoundException)
			{
				return null;
			}
		}


		/// <summary>
		/// Returns the list of TV shows that match a name
		/// </summary>
		public override List<TVShowPluginId> GetSimilarShows(FuzzyString ShowName)
		{
			List<TVShowPluginId> MatchingShows = new List<TVShowPluginId>();

			foreach (KeyValuePair<string, QueryPluginCached.CachedShow> CachedName in CachedShows)
			{
				FuzzyString FS = new FuzzyString(CachedName.Value.Name);
				int FuzzyComarisonResult = ShowName.Compare(FS);
				if (FuzzyComarisonResult >= (int) FuzzyString.Resemblance.Similar)
				{
					TVShowPluginId Match = new TVShowPluginId();
					Match.PluginInstance = this;
					Match.ShowId = CachedName.Key;
					Match.Weight = (int)FuzzyComarisonResult;
					MatchingShows.Add(Match);
				}

			}

			return MatchingShows;
		}


    }

}


